Amazon Linux で、Hyper-Threading を無効化する方法
はじめに
EC2 インスタンスを稼働させる AWS 基盤(仮想ホストサーバー)では、インテル®︎ ハイパースレッディング・テクノロジー(以降、HT)が利用可能な Xeon プロセッサーが利用されております。HT については、インテル社の公式サイトをご確認ください。
2017/10 現在、AWS から提供されている EC2 インスタンスの仮想CPU 数は、論理コア数に相当しているため仮想CPU 数を 1/2 した個数分の物理コアが割り当てられていると理解できます。ただし、一部(※)の特定インスタンスを除きます。
- インスタンスタイプ - Amazon EC2 (仮想サーバー) | AWS (※) 2017/10 現在、T2 および m3.medium を除く。
本記事では、Amazon Linux を利用した場合に OS インスタンス上から HT設定を無効化(つまり、仮想CPU 数を 1/2 した物理コア数に変更)する方法についてご紹介します。
HT の設定を無効化する場合のユースケースですが、以下の資料にて FPU heavy なアプリケーション(つまり、浮動⼩数点演算が多いアプリ)を利用する場合であることが紹介されております。
前提
本記事では、以下の環境を想定し検証を実施しました。
- c4.xlarge
- Amazon Linux AMI 2017.09.1 (HVM), SSD Volume Type - ami-2803ac4e
なお、Linux 環境では CPU番号は 物理CPUコア → 物理CPUコア → 論理CPUコア → 論理CPUコア の順に並び Windows 環境の場合は、インターリーブされるようです。(つまり 物理CPUコア → 論理CPUコア → 物理CPUコア → 論理CPUコア のように交互に配置される)
設定方法
一時的に設定を変更(無効化)するには、以下のコマンドを実行します。(インデックスの番号は、環境に合わせて置き換えが必要) 設定するコア数が少なければインデックス番号は直接指定で問題ありません。
$ sudo su - # for i in `seq <無効化設定するCPU番号の開始インデックス> <無効化設定するCPU番号の終了インデックス>`; do echo 0 > /sys/devices/system/cpu/cpu${i}/online done
無効化した設定を再度有効化するには、/sys/devices/system/cpu/cpuX/online に対して "1" を設定するか EC2 インスタンスを再起動するだけです。
恒久的に HyperThreading を無効化したい場合は、カーネルのブートパラメータに maxcpu=<物理コア数>の設定を追加し EC2 インスタンスを再起動します。
$ sudo su - # grubby --info=ALL index=0 kernel=/boot/vmlinuz-4.9.58-18.55.amzn1.x86_64 args="console=tty1 console=ttyS0 selinux=0 nvme_core.io_timeout=4294967295" root=LABEL=/ initrd=/boot/initramfs-4.9.58-18.55.amzn1.x86_64.img # grubby --args "maxcpus=2" --update-kernel /boot/vmlinuz-4.9.58-18.55.amzn1.x86_64 # grubby --info=ALL index=0 kernel=/boot/vmlinuz-4.9.58-18.55.amzn1.x86_64 args="console=tty1 console=ttyS0 selinux=0 nvme_core.io_timeout=4294967295 maxcpus=2" root=LABEL=/ initrd=/boot/initramfs-4.9.58-18.55.amzn1.x86_64.img # shutdown -r now
では、検証してみます。
実機検証
まずは、c4.xlarge インスタンスを起動し lscpu(1) で構成されている CPU リソースを確認します。
$ lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 4 On-line CPU(s) list: 0-3 Thread(s) per core: 2 Core(s) per socket: 2 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 63 Model name: Intel(R) Xeon(R) CPU E5-2666 v3 @ 2.90GHz Stepping: 2 CPU MHz: 2900.004 BogoMIPS: 5876.97 Hypervisor vendor: Xen Virtualization type: full L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 25600K NUMA node0 CPU(s): 0-3
上記の情報から、1 Socket / 2 Core / 4 Thread のリソースが構成されていることが確認できます。 次に、詳細情報を確認していきます。
$ cat /proc/cpuinfo | grep -e 'core id' -e processor processor : 0 core id : 0 processor : 1 core id : 1 processor : 2 core id : 0 processor : 3 core id : 1
上記の情報から、以下であると推測できます。
CPU番号 | 物理コア番号 |
---|---|
CPU#0 | 物理コア#0 |
CPU#1 | 物理コア#1 |
CPU#2 | 物理コア#0(の論理コア) |
CPU#3 | 物理コア#1(の論理コア) |
では、論理コアのペアを確認してみます。
$ cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list \ > | sort --unique --numeric-sort 0,2 1,3
CPU#0 - CPU#2 および CPU#1 - CPU#3 がそれぞれ同じ物理コアであることが確認できました。 そのため、本記事では CPU#2 および CPU#3 を無効化します。
$ sudo su - # for i in 2 3 echo 0 > /sys/devices/system/cpu/cpu${i}/online done
CPU#2 および #3 をオフラインに設定しました。状態を確認してみます。
$ lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 4 On-line CPU(s) list: 0,1 Off-line CPU(s) list: 2,3 ★オフラインに変更されている Thread(s) per core: 1 Core(s) per socket: 2 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 63 Model name: Intel(R) Xeon(R) CPU E5-2666 v3 @ 2.90GHz Stepping: 2 CPU MHz: 2900.004 BogoMIPS: 5876.93 Hypervisor vendor: Xen Virtualization type: full L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 25600K NUMA node0 CPU(s): 0,1
問題なく変更されているようです。 ちなみに、コアあたりのスレッド数が "2" から "1" に変わっています。
最後に
AWS 基盤側の技術的な詳細情報ってあまり公開されていないんだろうなーと勝手に思い込んでいましたが、今更ながら昨年の re:Invent にて Deep Dive on Amazon EC2 Instances という資料が公開されていることに気付き驚きました。なお、弊社では今年も AWS re:Invent 2017 に参加致します。なんと今年は、34名が現地での参加となります。
AWS re:Invent 2017 が気になる読者の方は、以下の記事も合わせて参照頂けると幸いです。
ではでは